package com.huizu.project.apiController;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.huizu.common.annotation.Anonymous;
import com.huizu.common.annotation.Log;
import com.huizu.common.config.UnAppConfig;
import com.huizu.common.constant.Constants;
import com.huizu.common.core.controller.BaseController;
import com.huizu.common.core.domain.AjaxResult;
import com.huizu.common.core.domain.entity.SysUser;
import com.huizu.common.core.redis.RedisCache;
import com.huizu.common.enums.BusinessType;
import com.huizu.common.exception.ServiceException;
import com.huizu.common.utils.MessageUtils;
import com.huizu.common.utils.SmsUtil;
import com.huizu.framework.manager.AsyncManager;
import com.huizu.framework.manager.factory.AsyncFactory;
import com.huizu.project.domain.ProUser;
import com.huizu.project.domain.ProUserTer;
import com.huizu.project.service.IProUserService;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Anonymous
@RestController
@RequestMapping("/api/login")
public class ApiLoginController extends BaseController {

    @Autowired
    private IProUserService proUserService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private UnAppConfig config;

    @PostMapping("/getOpenId")
    public AjaxResult getOpenId(String code) {
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + config.getAppStudentId() + "&secret=" + config.getAppStudentSecret() + "&js_code=" + code + "&grant_type=authorization_code";
        try {
            Map<String,Object> map = new HashMap<>();
            HttpClient client = HttpClients.createDefault();
            HttpGet get = new HttpGet(url);
            HttpResponse response = client.execute(get);
            String json = EntityUtils.toString(response.getEntity(), "UTF-8");
            String openId =JSONUtil.parseObj(json).get("openid",String.class);
            map.put("openId",openId);
            Boolean flag;
            ProUser proUser= proUserService.selectProUserByOpenId(openId);
            if (ObjectUtil.isNotEmpty(proUser)){
                flag =Boolean.TRUE;
            }else{
                flag =Boolean.FALSE;
            }
            map.put("flag",flag);
            return AjaxResult.success(map);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("获取微信openId失败");
        }
    }

    @PostMapping("/getPhoneNumber")
    public Object getPhoneNumber(@RequestBody Map<String,Object> data)
    {
        //通过appid和secret来获取token
        //WXContent.APPID是自定义的全局变量
        String tokenUrl = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", config.getAppStudentId(), config.getAppStudentSecret());
        JSONObject token = JSON.parseObject(HttpUtil.get(tokenUrl));

        //通过token和code来获取用户手机号
        String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + token.getString("access_token");

        //封装请求体
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("code", data.get("code").toString());

        //封装请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(paramMap,headers);

        //通过RestTemplate发送请求，获取到用户手机号码
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<Object> response = restTemplate.postForEntity(url, httpEntity, Object.class);

        //返回到前端展示
        return response.getBody();
    }

    /**
     * 登录-账号密码
     * @param proUser
     * @return
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody ProUser proUser){
        String phone = proUser.getPhone();
//        AsyncManager.me().execute(AsyncFactory.recordLogininfor("移动端学生登录：手机号" + phone, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        return proUserService.login(proUser);
    }

    /**
     * 副本：返回参数加密：登录-账号密码
     * @param proUser
     * @return
     */
    @PostMapping("/loginDeputy")
    public AjaxResult loginDeputy(@RequestBody ProUser proUser) throws JsonProcessingException {
        return proUserService.loginDeputy(proUser);
    }

    /**
     * 发送验证码
     * @param proUser
     * @return
     */
    @PostMapping("/sms")
    public AjaxResult sms(@RequestBody ProUser proUser){
        ProUser user= proUserService.selectProUserByStNumber(proUser.getStNumber());
        if (ObjectUtil.isEmpty(user)){
            throw new ServiceException("输入学号不存在");
        }

        if (!proUser.getPhone().equals(user.getPhone())){
            throw new ServiceException("输入手机号错误");
        }
        String code = SmsUtil.generateVerificationCode();
        SmsUtil.sendMessage(proUser.getPhone(),code);
        redisCache.setCacheObject("STUDENT:"+proUser.getPhone(),code,300, TimeUnit.SECONDS);
        return AjaxResult.success();
    }

    /**
     * 注册
     * @param proUser
     * @return
     */
    @PostMapping("/register")
    public AjaxResult register(@RequestBody ProUser proUser){
        return proUserService.register(proUser);
    }

    /**
     * 修改密码
     * @param proUser
     * @return
     */
    @PostMapping("/updatePassword")
    public AjaxResult updatePassword(@RequestBody ProUser proUser){
        return proUserService.updatePassword(proUser);
    }

    @PostMapping("/getOpenIdTer")
    public AjaxResult getOpenIdTer(String code) {
        Map<String,Object> map = new HashMap<>();
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + config.getAppTeacherId() + "&secret=" + config.getAppTeacherSecret() + "&js_code=" + code + "&grant_type=authorization_code";
        try {
            HttpClient client = HttpClients.createDefault();
            HttpGet get = new HttpGet(url);
            HttpResponse response = client.execute(get);
            String json = EntityUtils.toString(response.getEntity(), "UTF-8");
            String openId =JSONUtil.parseObj(json).get("openid",String.class);
            map.put("openId",openId);
            Boolean flag;
            SysUser sysUser= proUserService.selectSysUserByOpenId(openId);
            if (ObjectUtil.isNotEmpty(sysUser)){
                flag =Boolean.TRUE;
            }else{
                flag =Boolean.FALSE;
            }
            map.put("flag",flag);
            return AjaxResult.success(map);
        } catch (Exception e) {
            throw new ServiceException("获取微信openId失败");
        }
    }

    @PostMapping("/getPhoneNumberTer")
    public Object getPhoneNumberTer(@RequestBody Map<String,Object> data)
    {
        //通过appid和secret来获取token
        //WXContent.APPID是自定义的全局变量
        String tokenUrl = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", config.getAppTeacherId(), config.getAppTeacherSecret());
        JSONObject token = JSON.parseObject(HttpUtil.get(tokenUrl));

        //通过token和code来获取用户手机号
        String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + token.getString("access_token");

        //封装请求体
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("code", data.get("code").toString());

        //封装请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(paramMap,headers);

        //通过RestTemplate发送请求，获取到用户手机号码
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<Object> response = restTemplate.postForEntity(url, httpEntity, Object.class);
        //返回到前端展示
        return response.getBody();
    }
    @PostMapping("/loginTer")
    public AjaxResult loginTer(@RequestBody SysUser sysUser){
        AjaxResult ajaxResult = proUserService.loginTer(sysUser);
        String phone = sysUser.getPhone();
//        AsyncManager.me().execute(AsyncFactory.recordLogininfor("移动端教师登录：手机号" + phone, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        return ajaxResult;
    }

    /**
     * 发送验证码
     * @param sysUser
     * @return
     */
    @PostMapping("/smsTer")
    public AjaxResult smsTer(@RequestBody SysUser sysUser){
        SysUser user= proUserService.selectSysUserByJsNumber(sysUser.getJsNumber());
        if (ObjectUtil.isEmpty(user)){
            throw new ServiceException("输入工号不存在");
        }

        if (!sysUser.getPhone().equals(user.getPhone())){
            throw new ServiceException("输入手机号错误");
        }
        String code = SmsUtil.generateVerificationCode();
        SmsUtil.sendMessage(sysUser.getPhone(),code);

        redisCache.setCacheObject("TEACHER:"+sysUser.getPhone(),code,300, TimeUnit.SECONDS);
        return AjaxResult.success();
    }

//    @PostMapping("/loginTer2")
//    public AjaxResult loginTer2(@RequestBody SysUser sysUser){
//        return proUserService.loginTer(proUser);
//    }

    /**
     * 修改密码
     * @param proUser
     * @return
     */
    @PostMapping("/updatePasswordTer")
    public AjaxResult updatePasswordTer(@RequestBody ProUserTer proUser){
        return proUserService.updatePasswordTer(proUser);
    }
}
